package com.lhl.jwt.provider;

import cn.hutool.core.text.StrFormatter;
import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.hutool.crypto.digest.Digester;
import com.lhl.jwt.domain.entity.SysUser;
import com.lhl.jwt.excepiton.WxException;
import com.lhl.jwt.repository.UserRepository;
import com.lhl.jwt.token.WxAuthenticationToken;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.Optional;

/**
 * @className: com.lhl.jwt.provider.WxAuthenticationProvider
 * @description: TODO 类描述
 * @author: king
 * @date: 2020-11-17
 **/
@Api(tags = "WxAuthenticationProvider", produces = "")
@Slf4j
public class WxAuthenticationProvider implements AuthenticationProvider {
    @Autowired
    private UserRepository userRepository;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        WxAuthenticationToken wxAuthenticationToken = null;
        if (authentication instanceof WxAuthenticationToken) {
            wxAuthenticationToken = (WxAuthenticationToken) authentication;
        }
        String openId = (String) authentication.getCredentials();
        SysUser sysUser = userRepository.findByOpenId(openId);
        //执行注册逻辑
        if (sysUser == null) {
            log.debug("进行会员注册");
           //签名校验
            Digester digester = new Digester(DigestAlgorithm.SHA1);
            String data = wxAuthenticationToken.getRawData() + wxAuthenticationToken.getSessionKey();
            String signature = digester.digestHex(data);
            if (!wxAuthenticationToken.getSignature().equals(signature)) {
                log.error("signature is invalid, [{}] vs [{}]", signature, wxAuthenticationToken.getSignature());
                throw new WxException(StrFormatter.format("signature is invalid, {} vs {}", signature, wxAuthenticationToken.getSignature()));
            }

        }
        return new WxAuthenticationToken(openId, AuthorityUtils.commaSeparatedStringToAuthorityList(sysUser.getRole()));

        /*SysUser sysUser = userRepository.findByUsername(openId)
                .orElseThrow(() -> new UsernameNotFoundException("User Not Found with username: " + openId));
        return new WxAuthenticationToken(openId, AuthorityUtils.commaSeparatedStringToAuthorityList(sysUser.getRole()));*/
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return  WxAuthenticationToken.class.isAssignableFrom(authentication);
    }
}
